#include "clientFunc.h"

// cwd栈出栈
int pop(cwd_t *pcwd) {
    if(pcwd->size == 0) {
        return -1;
    }
    pathToken_t* temp = pcwd->top;
    if(temp->pnext != NULL) {
        temp->pnext->pfront = NULL;
    }
    pcwd->top = temp->pnext;
    free(temp);
    pcwd->size--;
    if(pcwd->size == 0) {
        pcwd->bottom = NULL;
    }
    return 0;
}

// cwd栈入栈
int push(cwd_t *pcwd,const char *data) {
    pathToken_t* pathToken = (pathToken_t*) calloc(1, sizeof(pathToken_t));
    strcpy(pathToken->data, data);

    if(pcwd->top == NULL) {
        pcwd->top = pathToken;
        pcwd->bottom = pathToken;
    }
    else {
        pathToken->pnext = pcwd->top;
        pcwd->top->pfront = pathToken;
        pcwd->top = pathToken;
    }
    pcwd->size++;
    return 0;
}

// 清除所有目录栈
int clear(cwd_t *pcwd) {
    pathToken_t* pathToken = pcwd->top;
    while(pathToken != NULL) {
        pathToken_t* temp = pathToken;
        pathToken = pathToken->pnext;
        free(temp);
    }
    pcwd->top = NULL;
    pcwd->bottom = NULL;
    pcwd->size = 0;
    return 0;
}

// 处理当前的token，对cwd进行相应的出栈入栈
int cwdCtl(cwd_t *pcwd, char* token) {
    if(strcmp(token, "..") == 0) {
        pop(pcwd);
    }
    else if(strcmp(token, ".") != 0){
        push(pcwd, token);
    }

    return 0;
}

// 真拷贝整个栈
int cwdCpy(cwd_t* pcwdSrc, cwd_t* pcwdCpy) {
    pathToken_t* token = pcwdSrc->bottom;
    while(token != NULL) {
        push(pcwdCpy, token->data);
        token = token->pfront;
    }
    return 0;
}

// 销毁整个栈
int destoryCwd(cwd_t* pcwd) {
    pathToken_t* token = pcwd->bottom;
    while(token != NULL && token->pfront != NULL) {
        pathToken_t* temp = token;
        token = token->pfront;
        free(temp);
    }
    free(pcwd);
    return 0;
}

// 通过传入的虚拟地址，修改cwd栈的结构
int parsePath(cwd_t *pcwd, char* virtualPath) {
    if(virtualPath[0] == '/') {
        clear(pcwd);
    }
    char* token;
    const char delim[] = "/";
    token = strtok(virtualPath, delim);
    if(token != NULL) {
        cwdCtl(pcwd, token);
    }
    else {
        return 0;
    }
    while((token = strtok(NULL, delim)) != NULL) {
        cwdCtl(pcwd, token);
    }
    return 0;
}

// 取出cwd栈中所存的路径, pwdstr用于存储路径
int getPath(const cwd_t *pcwd, char *pwdstr) {
    memset(pwdstr, 0, ARGVLEN);
    pathToken_t* pathToken = pcwd->bottom;
    strcat(pwdstr, "/");
    while(pathToken != NULL) {
        strcat(pwdstr, pathToken->data);
        pathToken = pathToken->pfront;
        strcat(pwdstr, "/");
    }
    if(strlen(pwdstr) != 1) {
        pwdstr[strlen(pwdstr) - 1] = '\0';
    }
    return 0;
}

// 根据传入的路径(cmd_t结构体中的一个argv字符串,可相对可绝对)
// 获取一个数据库目录系统的绝对路径
int realServerPath(cwd_t* pcwd, char* argv) {
    cwd_t* cwd = (cwd_t*)calloc(1, sizeof(cwd_t));
    cwdCpy(pcwd, cwd);
    parsePath(cwd, argv);
    getPath(cwd, argv);
    destoryCwd(cwd);
    return 0;
}
